package com.maigao.service;

import com.maigao.entity.form.AddTakeOffRecordForm;
import com.maigao.entity.jpa.ClassRecord;
import com.maigao.entity.jpa.Coach;
import com.maigao.entity.jpa.Student;
import com.maigao.entity.jpa.TakeOffRecord;
import com.maigao.entity.vo.TakeOffRecordVO;
import com.maigao.persistent.*;
import com.maigao.util.CollectionUtils;
import com.maigao.util.DateUtils;
import com.maigao.util.context.Context;
import com.maigao.util.context.user.User;
import com.maigao.persistent.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @program: maigao
 * @description:
 * @author: yongza
 * @create: 2024-10-23 23:38
 **/
@Service
public class TakeOffRecordService {
    @Autowired
    private TakeOffRecordRepository takeOffRecordRepository;
    @Autowired
    private ClassRecordRepository classRecordRepository;
    @Autowired
    private StudentRepository studentRepository;
    @Autowired
    private CoachRepository coachRepository;
    @Autowired
    private UserRepository userRepository;

    public Pair<Boolean, String> addTakeOff(AddTakeOffRecordForm form) {
        Integer classRecordId = form.getClassRecordId();
        if (StringUtils.isBlank(form.getStudentName()) || null == form.getStudentId() || null == classRecordId) {
            return Pair.of(false, "参数不完整!");
        }
        List<TakeOffRecord> takeOffRecords = takeOffRecordRepository.findByClassRecordId(classRecordId);
        if (CollectionUtils.isNotEmpty(takeOffRecords)) {
            if (takeOffRecords.stream().anyMatch(x -> x.getStatus() == TakeOffRecord.Status.CREATED.getValue()
                    || x.getStatus() == TakeOffRecord.Status.AUDIT_PASS.getValue())) {
                return Pair.of(false, "当前课程状态不允许请假!");
            }
        }
        ClassRecord classRecord = classRecordRepository.findById(classRecordId);
        if (LocalDateTime.now().isAfter(classRecord.getClassFromTime())) {
            return Pair.of(false, "当前时间已过上课时间, 不允许请假!");
        }
        TakeOffRecord record = new TakeOffRecord();
        record.setStudentId(form.getStudentId());
        record.setStudentName(form.getStudentName());
        record.setClassRecordId(classRecordId);
        record.setStatus(TakeOffRecord.Status.CREATED.getValue());
        record.setCreateTime(LocalDateTime.now());
        takeOffRecordRepository.save(record);
        return Pair.of(true, "");
    }

    public Pair<Boolean, String> revoke(Integer recordId) {
        TakeOffRecord takeOffRecord = takeOffRecordRepository.findById(recordId);
        if (null == takeOffRecord) {
            return Pair.of(false, "当前请假单不存在!");
        }
        if (takeOffRecord.getStatus() != TakeOffRecord.Status.CREATED.getValue()) {
            return Pair.of(false, "当前状态不允许撤销!");
        }
        takeOffRecord.setStatus(TakeOffRecord.Status.REVOKED.getValue());
        takeOffRecordRepository.save(takeOffRecord);
        return Pair.of(true, "");
    }

    public Pair<Boolean, String> audit(Integer recordId, Integer auditStatus, String reason) {
        if (null == auditStatus) {
            return Pair.of(false, "状态不能为空!");
        }
        User user = Context.current().getUser();
        TakeOffRecord takeOffRecord = takeOffRecordRepository.findById(recordId);
        if (null == takeOffRecord) {
            return Pair.of(false, "当前请假单不存在!");
        }
        if (takeOffRecord.getStatus() != TakeOffRecord.Status.CREATED.getValue()) {
            return Pair.of(false, "当前状态不允许审核!");
        }
        TakeOffRecord.Status statusEnum = TakeOffRecord.Status.getByValue(auditStatus);
        if (null == statusEnum) {
            return Pair.of(false, "状态非法!");
        }
        takeOffRecord.setStatus(statusEnum.getValue());
        takeOffRecord.setNote(reason);
        takeOffRecord.setApproveUserUid(user.getUid());
        takeOffRecord.setApproveUserName(user.getUserName());
        takeOffRecord.setNoticeStatus(TakeOffRecord.NoticeStatus.NEED_NOTICE.getValue());
        takeOffRecordRepository.save(takeOffRecord);
        ClassRecord classRecord = classRecordRepository.findById(takeOffRecord.getClassRecordId());
        classRecord.setStatus(ClassRecord.Status.ABANDON.getValue());
        classRecordRepository.save(classRecord);
        return Pair.of(true, "");
    }

    public Triple<Boolean, String, List<TakeOffRecordVO>> findStudentTakeOffRecord(String fromTime, String endTime) {
        List<Student> students = getCurrentStudents();
        if (CollectionUtils.isEmpty(students)) {
            return Triple.of(false, "获取学生信息失败!", null);
        }
        List<Integer> studentIds = students.stream().map(Student::getId).collect(Collectors.toList());
        LocalDate fromDate = DateUtils.parseDate(fromTime, DateUtils.Formatter.DATE_YYYY_MM_DD);
        LocalDate endDate = DateUtils.parseDate(endTime, DateUtils.Formatter.DATE_YYYY_MM_DD);
        LocalDateTime from = LocalDateTime.of(fromDate, LocalTime.MIN);
        LocalDateTime end = LocalDateTime.of(endDate, LocalTime.MAX);
        List<TakeOffRecord> takeOffRecords = takeOffRecordRepository.findByStudentIdInAndCreateTimeBetween(studentIds, from, end);
        if (CollectionUtils.isEmpty(takeOffRecords)) {
            return Triple.of(false, "未查询到请假记录!", null);
        }
        return Triple.of(true, "", convert2Detail(takeOffRecords));
    }

    public List<TakeOffRecordVO> convert2Detail(List<TakeOffRecord> takeOffRecords) {
        List<TakeOffRecordVO> takeOffRecordVOS = new ArrayList<>();
        for (TakeOffRecord takeOffRecord : takeOffRecords) {
            TakeOffRecordVO takeOffRecordVO = new TakeOffRecordVO();
            BeanUtils.copyProperties(takeOffRecord, takeOffRecordVO);
            takeOffRecordVO.setCreateTime(DateUtils.format(takeOffRecord.getCreateTime(), DateUtils.Formatter.DATETIME_YYYY_MM_DD_HH_MM_SS));
            takeOffRecordVO.setLastUpdateTime(DateUtils.format(takeOffRecord.getLastUpdateTime(), DateUtils.Formatter.DATETIME_YYYY_MM_DD_HH_MM_SS));
            takeOffRecordVOS.add(takeOffRecordVO);
        }
        return takeOffRecordVOS;
    }

    public Triple<Boolean, String, List<TakeOffRecordVO>> findCoachNeedAuditTakeOffRecord() {
        Coach coach = getCurrentCoach();
        if (null == coach) {
            return Triple.of(false, "获取教练信息失败!", null);
        }
        List<Student> students = studentRepository.findByCoachId(coach.getId());
        List<Integer> studentIds = students.stream().map(Student::getId).collect(Collectors.toList());
        List<TakeOffRecord> takeOffRecords = takeOffRecordRepository.findByStudentIdInAndStatus(studentIds, TakeOffRecord.Status.CREATED.getValue());
        if (CollectionUtils.isEmpty(takeOffRecords)) {
            return Triple.of(false, "未查询到请假记录!", null);
        }
        return Triple.of(true, "", convert2Detail(takeOffRecords));
    }

    public Triple<Boolean, String, List<TakeOffRecordVO>> findAdminNeedAuditTakeOffRecord() {
        User user = Context.current().getUser();
        if (null == user) {
            return Triple.of(false, "获取教练信息失败!", null);
        }
        com.maigao.entity.jpa.User dbUser = userRepository.findByUid(user.getUid());
        int adminType = com.maigao.entity.jpa.User.UserType.ADMIN.getValue();
        if (dbUser.getUserType() != adminType) {
            return Triple.of(false, "当前用户没有管理员权限!", null);
        }
        List<TakeOffRecord> takeOffRecords = takeOffRecordRepository.findByStatus(TakeOffRecord.Status.CREATED.getValue());
        if (CollectionUtils.isEmpty(takeOffRecords)) {
            return Triple.of(false, "未查询到请假记录!", null);
        }
        return Triple.of(true, "", convert2Detail(takeOffRecords));
    }

    private Coach getCurrentCoach() {
        User user = Context.current().getUser();
        String uid = user.getUid();
        return coachRepository.findByUserUid(uid);
    }

    private List<Student> getCurrentStudents() {
        User user = Context.current().getUser();
        String uid = user.getUid();
        return studentRepository.findByUserUid(uid);
    }
}
